

#ifdef __cplusplus
extern "C"
{
#endif

#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#ifdef __cplusplus
}
#endif

#include <iostream>
#include <atomic>


std::atomic_bool atomic_malloc_enable{true};

typedef void* (*real_malloc)(size_t size);
typedef void  (*read_free)(void *ptr);

static real_malloc r_malloc;
static read_free   r_free;

void hook_init()
{
    if (!r_malloc)
    {
        r_malloc = (real_malloc)dlsym(RTLD_NEXT, "malloc");
    }
    if (!r_free)
    {
        r_free   = (read_free)dlsym(RTLD_NEXT, "free");
    }
}

void *malloc(size_t size)
{
    hook_init();
    void *p = nullptr;
    if (atomic_malloc_enable.load())
    {
        atomic_malloc_enable.store(false);
        // printf : call malloc
        p = r_malloc(size);
        char buf[64] = {};
        snprintf(buf, sizeof(buf), "./mem/%p.txt", p);
        FILE* fd = fopen(buf, "w");
        snprintf(buf, sizeof(buf), "size(%ld)addr(%p)func(%p)\n", size, p, __builtin_return_address(0));
        fwrite(buf, sizeof(buf), 1, fd);
        fflush(fd);
        fclose(fd);
        atomic_malloc_enable.store(true);
    }
    else
    {
        p = r_malloc(size);
    }

    return p;
}

void free(void *ptr)
{
    hook_init();
    r_free(ptr);
    char buf[64] = {};
    snprintf(buf, sizeof(buf), "./mem/%p.txt", ptr);
    unlink(buf);
}


// 手动创建mem文件夹
// addr2line -f -e "a.out" -a 0x????
int main()
{
    hook_init();
    if (!r_malloc || !r_free)
    {
        return -1;
    }


    int *p1 = (int *)malloc(100);
    int *p2 = (int *)malloc(100);
    int *p3 = (int *)malloc(30);
    int *p5 = new int{7};
    int *p6 = new int{8};
    int *p7 = new int[7];

    free(p1);
    free(p2);
    return 0;
}